package test;

import static org.junit.Assert.*;
import Phase2.Node;
import java.util.TreeSet;

import junit.framework.Assert;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class testWhiteBoxInsertPointAlg 
{
	private final boolean rootAccess = false;
	private Node baseNode;
	private TreeSet<Node> hypeerWeb;
	
	/**
	 * Code Coverage - 100% of all code that can be reasonably tested is covered
	 * Branch Coverage
	 * Condition Testing
	 * Loop Testing
	 * Data Flow
	 * Internal Boundary Testing
	 */
	
	/**
	 * Data Flow Testing:
	 * 		There are two test cases that specifically target and check that the getInsertionPoint algorithm goes through the UpState
	 * 		and the Last state to check they are working properly.  Nodes in the DownState and the Empty State are also checked in order
	 * 		to do the previous Data Flow tests.  This follows all the data paths the getInsertionPoint algorithm must go through.
	 * 
	 * Branch Coverage:
	 * 		In performing Data Flow Testing, all the different branches the code goes through that can reasonably be tested on a single
	 * 		machine are followed.
	 * 
	 * Condition Testing:
	 * 		In performing Data Flow Testing. The few if statements and other conditional tests are followed to give partial condition testing
	 * 		for each branch (true or false) for a given statement.
	 * 
	 * LoopTesting:
	 * 		Loops are found in the insertion algorithm and as each Node is added the different states of the loop ( executing one time, two times, many times,
	 * 		or no times) are followed to test the loops of the insertion algorithm to make sure everything is correct.
	 * 
	 * Internal Boundary Testing:
	 * 		The only real internal boundaries for the insertion algorithm are the states of a Node and special cases, such as when a Node
	 * 		has the web id of 0, and when it has some other id.  These cases are tested and accounted for in doing Data flow testing
	 * 		and when finding the insertion Point when there is only one Node
	 * 		
	 */
	
	@Before
	public void setUp()
	{
		baseNode = new Node();
		hypeerWeb = new TreeSet<Node>();
		hypeerWeb.add(baseNode);
	}
	
	@Test
	public void lastStateInsertion() throws InterruptedException
	{
		Node insertNode = new Node();
		Node checkNode = new Node();;
		baseNode.insert(insertNode);
		hypeerWeb.add(insertNode);
		assertEquals(0, insertNode.getParent(rootAccess).getId(rootAccess));
		
		for (int i = 0; i < 3; i++)
		{
			insertNode = new Node();
			baseNode.insert(insertNode);
			hypeerWeb.add(insertNode);
			if (i == 1)
			{ checkNode = insertNode; }
		}
		insertNode = new Node();
		checkNode.insert(insertNode);
		hypeerWeb.add(insertNode);
		
		assertEquals(3, checkNode.getId(rootAccess));
		assertEquals(1, insertNode.getParent(rootAccess).getId(rootAccess));
		for (int i = 0; i < 10; i++)
		{
			insertNode = new Node();
			baseNode.insert(insertNode);
			hypeerWeb.add(insertNode);
			if(i == 1)
			{ checkNode = insertNode; }
			
		}
		System.out.println(checkNode.getState(rootAccess) + " " + hypeerWeb.size());
		insertNode = new Node();
		checkNode.insert(insertNode);
		hypeerWeb.add(insertNode);

		assertEquals(7, checkNode.getId(rootAccess));
		assertEquals(0, insertNode.getParent(rootAccess).getId(rootAccess));
		
	}
		
	@Test
	public void upStateInsertion() throws InterruptedException
	{
		Node insertNode;
		Node checkNode = new Node();
		
		for (int i = 0; i < 2; i++)
		{
			insertNode = new Node();
			hypeerWeb.add(insertNode);
			baseNode.insert(insertNode);
			if (i == 1) 
			{ checkNode = insertNode; }
		}
		insertNode = new Node();
		checkNode.insert(insertNode);
		hypeerWeb.add(insertNode);
		assertEquals(1, insertNode.getParent(rootAccess).getId(rootAccess));
		
		for (int i = 0; i < 5; i++)
		{
			insertNode = new Node();
			baseNode.insert(insertNode);
			hypeerWeb.add(insertNode);
		}
		insertNode = new Node();
		checkNode.insert(insertNode);
		hypeerWeb.add(insertNode);

		assertEquals(1, insertNode.getParent(rootAccess).getId(rootAccess));
	}
	
	@After
	public  void tearDown()
	{
		hypeerWeb.clear();
	}
}
